package aOrganizar;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import aerolineasAdapters.AeroLanchitaAdapter;
import aerolineasAdapters.OceanicAdapter;
import fechas.FechaUtils;

public class ItinerarioMaker {

	private static ItinerarioMaker instance;
	private static Integer MAX_HORAS_ESCALA = 12;

	static {
		instance = new ItinerarioMaker();
	}

	private ItinerarioMaker() {

	}

	public static ItinerarioMaker getInstance() {

		return instance;
	}
	
	public static void setMaxEspera(Integer horas){
		ItinerarioMaker.MAX_HORAS_ESCALA = horas;
		
	}
	
	/**
	 * Delvuelve el todos los itinerarios disponibles para la busqueda pasada por parametro. 
	 * La fecha pasada por parametro en la busqueda es la fecha de salida del vuelo. 
	 * @param busqueda
	 * @param usuario
	 * @return
	 */
	public Collection<Itinerario> armarItinerario(Busqueda busqueda, Usuario usuario) {
		List<Itinerario> listItineriarios = new ArrayList<Itinerario>();
		List<Aerolinea> listAerolinea = new ArrayList<Aerolinea>();
		Itinerario itinerario = new Itinerario();
		Integer escala = 0;
		
		listAerolinea.add(new AeroLanchitaAdapter());
		listAerolinea.add(new OceanicAdapter());
		
		for (Aerolinea aerolinea : listAerolinea) {
			makeItinerarioByEscalas(listItineriarios, itinerario, aerolinea, escala, busqueda, usuario);
		}
		
		return listItineriarios;
	}

	private void makeItinerarioByEscalas(List<Itinerario> listItineriarios,Itinerario itinerario,
			Aerolinea aerolinea,int escala,Busqueda busqueda, Usuario usuario) {
		
		List<Asiento> listAsientos = new ArrayList<Asiento>();
		listAsientos = (List<Asiento>) aerolinea.findAsientosByOrigen(busqueda.getOrigen(), busqueda.getFecha(), usuario);
		for (Asiento asiento : listAsientos) {
			if(asiento.getVuelo().getDestino().equalsIgnoreCase(busqueda.getDestino()) && puedeHacerEscala(itinerario,asiento.getVuelo().getSalida())){
				Itinerario itinerarioNuevo = itinerario.clone();
				itinerario.getAsientos().add(asiento);
				listItineriarios.add(itinerario);
				itinerario = itinerarioNuevo;
			}
			else if(escala<busqueda.getCantEscalas()){
				Itinerario itinerarioNuevo = itinerario.clone();
				itinerario.getAsientos().add(asiento);
				//le paso la nueva busqueda
				Busqueda nuevaBusqueda = new Busqueda(busqueda.getDestino(),asiento.getVuelo().getDestino(),asiento.getVuelo().getLlegada(),busqueda.getCantEscalas());
				makeItinerarioByEscalas(listItineriarios, itinerario, aerolinea,escala+1,nuevaBusqueda, usuario);
				itinerario = itinerarioNuevo;
			}
		}
	}
	
	boolean puedeHacerEscala(Itinerario itinerario,Date fechaVuelo){
		if(itinerario.getAsientos().size()>0){
			Asiento asiento = itinerario.getAsientos().get(itinerario.getAsientos().size()-1);
			if(asiento!=null){
				Vuelo ultimoVuelo = asiento.getVuelo();
				Date fechaMaximaEspera = FechaUtils.addHours(ultimoVuelo.getLlegada(),MAX_HORAS_ESCALA);
				return (ultimoVuelo.getLlegada().before(fechaVuelo) && fechaVuelo.before(fechaMaximaEspera));
			}	
		}
		return true;
	}
}
